{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": 1,
   "metadata": {},
   "outputs": [
    {
     "name": "stderr",
     "output_type": "stream",
     "text": [
      "Using TensorFlow backend.\n"
     ]
    }
   ],
   "source": [
    "import numpy as np\n",
    "np.random.seed(1337) # 伪随机以保持一致\n",
    "from keras.datasets import mnist\n",
    "from keras.utils import np_utils\n",
    "from keras.models import Sequential\n",
    "from keras.layers import Dense, Activation, Conv2D, MaxPooling2D, Flatten\n",
    "from keras.optimizers import Adam"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "metadata": {
    "scrolled": false
   },
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "正在训练. . .\n",
      "Epoch 1/10\n",
      "60000/60000 [==============================] - 11s 178us/step - loss: 0.3150 - accuracy: 0.9146\n",
      "Epoch 2/10\n",
      "60000/60000 [==============================] - 8s 141us/step - loss: 0.1003 - accuracy: 0.9691\n",
      "Epoch 3/10\n",
      "60000/60000 [==============================] - 8s 140us/step - loss: 0.0645 - accuracy: 0.9798\n",
      "Epoch 4/10\n",
      "60000/60000 [==============================] - 8s 140us/step - loss: 0.0445 - accuracy: 0.9862\n",
      "Epoch 5/10\n",
      "60000/60000 [==============================] - 8s 138us/step - loss: 0.0303 - accuracy: 0.9902\n",
      "Epoch 6/10\n",
      "60000/60000 [==============================] - 8s 141us/step - loss: 0.0242 - accuracy: 0.9918\n",
      "Epoch 7/10\n",
      "60000/60000 [==============================] - 9s 146us/step - loss: 0.0194 - accuracy: 0.9937\n",
      "Epoch 8/10\n",
      "60000/60000 [==============================] - 9s 151us/step - loss: 0.0146 - accuracy: 0.9948\n",
      "Epoch 9/10\n",
      "60000/60000 [==============================] - 9s 152us/step - loss: 0.0140 - accuracy: 0.9954\n",
      "Epoch 10/10\n",
      "60000/60000 [==============================] - 9s 153us/step - loss: 0.0098 - accuracy: 0.9967\n",
      "正在测试. . .\n",
      "10000/10000 [==============================] - 1s 73us/step\n",
      "test loss: 0.0674502815180299\n",
      "test accuracy: 0.982699990272522\n"
     ]
    }
   ],
   "source": [
    "# 下载mnist数据集保存到\"c:\\users\\用户名\\.keras\\datasets\"(如果没有数据集)\n",
    "# X的形状(60,000 28x28), Y的形状(10,000,)\n",
    "(x_train, y_train), (x_test, y_test) = mnist.load_data()\n",
    "\n",
    "# 数据预处理\n",
    "x_train = x_train.reshape(-1, 1, 28, 28)# / 255\n",
    "x_test = x_test.reshape(-1, 1, 28, 28)# / 255\n",
    "\n",
    "y_train = np_utils.to_categorical(y_train, num_classes=10)\n",
    "y_test = np_utils.to_categorical(y_test, num_classes=10)\n",
    "\n",
    "# 构建卷积神经网络\n",
    "model = Sequential()\n",
    "\n",
    "# 卷积层1 输出:(32, 28, 28)\n",
    "model.add(Conv2D(\n",
    "        filters=32,\n",
    "        kernel_size = (5,5),\n",
    "        padding=\"same\",  # padding模式\n",
    "        input_shape=(1,28,28) # 通道个数 长 宽\n",
    "    ))\n",
    "model.add(Activation(\"relu\"))\n",
    "\n",
    "# 池化层1 输出:(32, 14, 14)\n",
    "model.add(MaxPooling2D(\n",
    "        pool_size=(2,2),\n",
    "        strides=(2, 2),       # 步长\n",
    "        padding=\"same\"\n",
    "    ))\n",
    "\n",
    "# 卷积层2 输出:(64, 14, 14)\n",
    "model.add(Conv2D(64, (5, 5), padding=\"same\"))\n",
    "model.add(Activation(\"relu\"))\n",
    "\n",
    "# 池化层2 输出:(64, 7, 7)\n",
    "model.add(MaxPooling2D(pool_size=(2, 2), padding=\"same\"))\n",
    "\n",
    "# 全连接层1 输入:(64 * 7 * 7) = 3136, 输出: 1024\n",
    "model.add(Flatten())\n",
    "model.add(Dense(1024))\n",
    "model.add(Activation(\"relu\"))\n",
    "# 全连接层 2 输入：1024 输出： 10(softmax)\n",
    "model.add(Dense(10))\n",
    "model.add(Activation(\"softmax\"))\n",
    "# 定义优化器\n",
    "adam = Adam(lr=1e-4)\n",
    "\n",
    "# 加入metrics来获得更多结果\n",
    "model.compile(optimizer=adam, loss=\"categorical_crossentropy\",)\n",
    "              #metrics=[\"accuracy\"])\n",
    "\n",
    "# 训练模型\n",
    "print(\"正在训练. . .\")\n",
    "model.fit(x_train, y_train, epochs=10, batch_size=32)\n",
    "\n",
    "# 测试模型和先前定义的metrics\n",
    "\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "metadata": {},
   "outputs": [
    {
     "name": "stdout",
     "output_type": "stream",
     "text": [
      "正在测试. . .\n",
      "10000/10000 [==============================] - 1s 59us/step\n",
      "test loss: 0.0674502815180299\n",
      "test accuracy: 0.982699990272522\n"
     ]
    }
   ],
   "source": [
    "print(\"正在测试. . .\")\n",
    "loss, accuracy = model.evaluate(x_test, y_test)\n",
    "\n",
    "print(\"test loss:\", loss)\n",
    "print(\"test accuracy:\", accuracy)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "metadata": {},
   "outputs": [],
   "source": [
    "model?"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.7.7"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 2
}